import cgi
import os

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext.webapp import template
from google.appengine.api import urlfetch

from django.utils import simplejson

import oauth 
import gmemsess
import ckeynsecret

REQUEST_TOKEN_URL = 'http://api.myspace.com/request_token'
AUTHORIZATION_URL = 'http://api.myspace.com/authorize'
ACCESS_TOKEN_URL = 'http://api.myspace.com/access_token'

API_PROFILE_URL = 'http://api.myspace.com/v2/people/@me/@self?format=json'
API_FRIENDS_URL = 'http://api.myspace.com/v2/people/@me/@friends?format=json'

CONSUMER_KEY    = ckeynsecret.CONSUMER_KEY
CONSUMER_SECRET = ckeynsecret.CONSUMER_SECRET

"""
Some helper methods
"""
consumer = oauth.OAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET)
signature_method = oauth.OAuthSignatureMethod_HMAC_SHA1()

def fetch_response(oauth_request, debug=False):
  url = oauth_request.to_url()
  rv = urlfetch.fetch(url)
  s = rv.content
  if debug:
    print 'requested url: %s' % url
    print 'server response: %s' % s
  return s
  
def get_unauthorized_request_token():
    oauth_request = oauth.OAuthRequest.from_consumer_and_token(
        consumer, http_url=REQUEST_TOKEN_URL
    )
    oauth_request.sign_request(signature_method, consumer, None)
    resp = fetch_response(oauth_request)
    token = oauth.OAuthToken.from_string(resp)
    return token

def get_authorization_url(token, callback_url):
    oauth_request = oauth.OAuthRequest.from_token_and_callback(
        token=token, callback=callback_url, http_url=AUTHORIZATION_URL
    )
    oauth_request.sign_request(signature_method, consumer, token)
    return oauth_request.to_url()

def exchange_request_token_for_access_token(request_token):
    oauth_request = oauth.OAuthRequest.from_consumer_and_token(
        consumer, token=request_token, http_url=ACCESS_TOKEN_URL
    )
    oauth_request.sign_request(signature_method, consumer, request_token)
    resp = fetch_response(oauth_request)
    return oauth.OAuthToken.from_string(resp) 

def get_profile(access_token):
    oauth_request = oauth.OAuthRequest.from_consumer_and_token(
        consumer, token=access_token, http_url=API_PROFILE_URL
    )
    oauth_request.sign_request(signature_method, consumer, access_token)
    json = fetch_response(oauth_request)
    return simplejson.loads(json)

def get_friends(access_token):
    oauth_request = oauth.OAuthRequest.from_consumer_and_token(
        consumer, token=access_token, http_url=API_FRIENDS_URL
    )
    oauth_request.sign_request(signature_method, consumer, access_token)
    json = fetch_response(oauth_request)
    return simplejson.loads(json)

"""
webapp handlers
1. / Index page, not logged in
   - Intro text plus link to auth with MySpace
2. /StartAuth Auth with MySpace
   - Creates an unauthed token, stashes in session, redirects user to MySpace
3. /OauthCallback Callback URL
   - Checks user's unauthed token session matches, if not shows error, otherwise
     exchanges for access token, stashes that in the session and redirects the
     user to /displayprofile page
4. /DisplayProfile
   - Looks up the user's profile and friends using their access token
"""
    
class IndexPage(webapp.RequestHandler):
    def get(self):
        session=gmemsess.Session(self)
        if 'access_token' in session:
            self.redirect('/displayprofile')
        else:
            path = os.path.join(os.path.dirname(__file__), 'templates/index.html')
            self.response.out.write(template.render(path, {}))

class StartAuth(webapp.RequestHandler):
    def get(self):
        session=gmemsess.Session(self)    
        callback_url = self.request.host_url + '/callback'
        token = get_unauthorized_request_token()
        auth_url = get_authorization_url(token, callback_url)
        session['unauthed_token'] = token.to_string()
        session.save()
        self.redirect(auth_url)

class OauthCallback(webapp.RequestHandler):
    def get(self):
        session=gmemsess.Session(self)
        unauthed_token = session['unauthed_token'] if 'unauthed_token' in session else None
        if not unauthed_token:
            self.response.out.write("No un-authed token found in session")
            return
        token = oauth.OAuthToken.from_string(unauthed_token)   
        if token.key != self.request.get('oauth_token', 'no-token'):
            self.response.out.write("Something went wrong! Tokens do not match")
            return
        access_token = exchange_request_token_for_access_token(token)
        session['access_token'] = access_token.to_string()
        session.save()
        self.redirect('/displayprofile')

class DisplayProfile(webapp.RequestHandler):
    def get(self):
        session=gmemsess.Session(self)
        access_token = session['access_token'] if 'access_token' in session else None
        if not access_token:
            self.response.out.write("You need an access token in the session!")
            return
        token = oauth.OAuthToken.from_string(access_token)    
        profile_info = get_profile(token)
        friends_info = get_friends(token)
        
        template_values = {
          'profile': profile_info,
          'friends': friends_info,
        }        
        path = os.path.join(os.path.dirname(__file__), 'templates/profile.html')
        self.response.out.write(template.render(path, template_values))


application = webapp.WSGIApplication(
                                     [('/', IndexPage),
                                      ('/startauth', StartAuth),
                                      ('/callback', OauthCallback),
                                      ('/displayprofile', DisplayProfile)],
                                     debug=True)

def main():
  run_wsgi_app(application)

if __name__ == "__main__":
  main()
